package com.coco.service.impl;

import com.coco.constant.MongoTableNameConst;
import com.coco.dao.VideoMapper;
import com.coco.model.NaviInfo;
import com.coco.model.VideoCondition;
import com.coco.model.VideoModel;
import com.coco.model.VideoNum;
import com.coco.service.NaviService;
import com.coco.service.VideoService;
import com.coco.utils.CoPageResp;
import com.mongodb.bulk.BulkWriteResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.util.Pair;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author GHOSTLaycoo
 * @date 2020/4/13 0013 - 上午 8:45
 */
@Service
public class VideoServiceImpl implements VideoService{

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private NaviService naviService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private MongoTemplate mongoTemplate;

    private static final Logger log = LoggerFactory.getLogger(VideoServiceImpl.class);

    @Override
    public CoPageResp<VideoModel> getVideosByCondition(VideoCondition videoCondition) {
        CoPageResp<VideoModel> result = null;
        int newIndex = (videoCondition.getPageIndex()-1)*videoCondition.getPageSize();
        videoCondition.setPageIndex(newIndex);
        List<VideoModel> userByCondition = videoMapper.getVideosByCondition(videoCondition);
        long countByCondition = videoMapper.getCountByCondition(videoCondition);
        if(!CollectionUtils.isEmpty(userByCondition) && userByCondition.size()>0){
            result = new CoPageResp<>();
            result.setData(userByCondition);
            result.setTotal(countByCondition);
        }
        return result;
    }

    @Override
    public int delete(String id) {
        return videoMapper.delete(id);
    }

    @Override
    public int save(VideoModel videoModel) {
        String uuid = UUID.randomUUID().toString();
        videoModel.setId(uuid);
        videoModel.setStar(0);
        videoModel.setCreateTime(new Date());
        videoModel.setUpdateTime(new Date());
        //发送mq消息
        amqpTemplate.convertAndSend("item.insert",videoModel.getVideoName());
        mongoTemplate.insert(videoModel, MongoTableNameConst.CoCo_Video);
        return videoMapper.save(videoModel);
    }

    @Override
    public int update(VideoModel videoModel) {
        videoModel.setUpdateTime(new Date());
        return videoMapper.update(videoModel);
    }

    @Override
    public List<VideoNum> getTypeNums() {
        List<VideoModel> allVideo = videoMapper.getAllVideo();
        Map<String, Long> collect = allVideo.stream().collect(Collectors.groupingBy(VideoModel::getTypeId, Collectors.counting()));
        Set<String> typeIds = allVideo.stream().map(VideoModel::getTypeId).collect(Collectors.toSet());
        List<NaviInfo> navis = naviService.getNavis();
        Map<String, String> collect1 = navis.stream().collect(Collectors.toMap(NaviInfo::getId, NaviInfo::getNaviName));
        List<VideoNum> videoNums = new ArrayList<>();
        typeIds.forEach(s->{
            VideoNum videoNum = new VideoNum();
            videoNum.setValue(collect.get(s));
            videoNum.setName(collect1.get(s));
            videoNums.add(videoNum);
        });
        return videoNums;
    }

    @Override
    public VideoModel getVideoById(String id) {
        return videoMapper.getVideoById(id);
    }

    @Override
    public int updateWatch(String id) {
        VideoModel videoById = getVideoById(id);
        long sum = videoById.getSum()+1;
        int i = videoMapper.updateWatch(id, sum);
        return i;
    }

    @PostConstruct
    public void init(){
        List<VideoModel> allVideo = videoMapper.getAllVideo();
        List<Pair<Query, Update>> updateList = new ArrayList<>(allVideo.size());
        BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, MongoTableNameConst.CoCo_Video);
        allVideo.forEach(data -> {
            Query query = new Query(new Criteria("_id").is(data.getId()));
            Update update = new Update();
            Field[] declaredFields = data.getClass().getDeclaredFields();
            for (Field declaredField : declaredFields) {
                try {
                    //把private改成public
                    declaredField.setAccessible(true);
                    update.set(declaredField.getName(),declaredField.get(data));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            Pair<Query, Update> updatePair = Pair.of(query, update);
            updateList.add(updatePair);
        });
        operations.upsert(updateList);
        BulkWriteResult result = operations.execute();
        log.info("初始化结果：",result);
    }

    @Override
    public int updateStar(String id, int sum) {
        return videoMapper.updateStar(id,sum);
    }
}
